/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with
 * the License.  You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import java.util.Random;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import junit.framework.TestCase;





/**
 * Performs Validation Test for url validations.
 *
 * @version $Revision: 1128446 $ $Date: 2011-05-27 13:29:27 -0700 (Fri, 27 May 2011) $
 */
public class UrlValidatorTest extends TestCase {

   // HN added these four from URLValidator.java to aid in the completion of the testIsValid() function.
   private static final String LEGAL_ASCII_REGEX = "^\\p{ASCII}+$";
   private static final Pattern ASCII_PATTERN = Pattern.compile(LEGAL_ASCII_REGEX);
   private static final String URL_REGEX =
           "^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?";
   //                                                                      12            3  4          5       6   7        8 9
   private static final Pattern URL_PATTERN = Pattern.compile(URL_REGEX);
	
   private boolean printStatus = false;
   private boolean printIndex = false;//print index that indicates current scheme,host,port,path, query test were using.

   public UrlValidatorTest(String testName) {
      super(testName);
   }
   
   // I just created this for simple debugging. Now I can just plug in and debug/localize a failure
/*   public void testSingleUrl(){
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
	   boolean valid = urlVal.isValid("http://www.google.com:8080/");
	   System.out.println("Should be: TRUE, is: "+valid);
	   System.exit(0);
   } */
   
   // comment out assertion to see all failing urls
   public void testManualTest()
   {	
	   System.out.println("\n\n** Manual Testing' ************************************************\n");
	   String[] urls = {"http://www.amazon.com", "http://www.google.co.uk/", "http://www.mywebsite.com?search=true", "ffg://test-site.com",
			   "http://www.metro.tokyo.jp/", "https://my-site.com:80", "ftp://gimme.gov:22", "ftp://www.randomurl.edu/index.php?param=2", "https://blah-blah-blah-blah.gov:34?me=true"};
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
	   for(int i = 0 ; i < urls.length ; i++){
		   System.out.println(urls[i] +" --> "+urlVal.isValid(urls[i]));
		   assertEquals(urlVal.isValid(urls[i]), true);
	   }
   }
   
   // testing https:// scheme
   // comment out assertion to see all failing urls
   public void testYourFirstPartition()
   {
	    System.out.println("\n\n** Partition Test 1: 'https://' ************************************************\n");
		UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
		String scheme = "https://";
		for(int i = 0; i < 1000 ; i++){
			URLGenerator url = URLGenerator.generateUrl(scheme, 10);
			if(urlVal.isValid(url.text) != url.valid)
				System.out.println("FAILED: isValid() = "+urlVal.isValid(url.text)+"\t"+url.text);
			assertEquals(urlVal.isValid(url.text), url.valid);
		}
   } 
   
   // testing ftp:// scheme
   // comment out assertion to see all failing urls
   public void testYourSecondPartition()
   {
	   System.out.println("\n\n** Partition Test 2: 'ftp://' ************************************************\n");
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);
		String scheme = "ftp://";
		for(int i = 0; i < 1000 ; i++){
			URLGenerator url = URLGenerator.generateUrl(scheme, 10);
			if(urlVal.isValid(url.text) != url.valid)
				System.out.println("FAILED: isValid() = "+urlVal.isValid(url.text)+"\t"+url.text);
			assertEquals(urlVal.isValid(url.text), url.valid);
		}
   }
   
   // comment out assertions to see all failing urls
   public void testIsValid()
   {
	   System.out.println(" ");
	   System.out.println("Now Running: testIsValid()");
	   System.out.println(" ");
	   
	   UrlValidator urlVal = new UrlValidator(null, null, UrlValidator.ALLOW_ALL_SCHEMES);		
	   String[] schemes = {"https://", "http://", "ftp://"};
	   Random r = new Random();
	   for(int i = 0;i<1000;i++)
	   {
		   int validityRate = 0;
		   URLGenerator value = URLGenerator.generateUrl(schemes[r.nextInt(schemes.length)], 10);							
			if(value.text == "null"){															
				System.out.println("invalid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
				validityRate++;
				assertEquals(urlVal.isValid(value.text), value.valid);									
		   }
			if(!ASCII_PATTERN.matcher(value.text).matches()){									
				System.out.println("invalid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
				validityRate++;
				assertEquals(urlVal.isValid(value.text), value.valid);									
		   }   
			
		   Matcher urlMatcher = URL_PATTERN.matcher(value.text);
		   if (!urlMatcher.matches()) {															
			   	System.out.println("invalid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
			   	validityRate++;
			   	assertEquals(urlVal.isValid(value.text), value.valid);									
		   }
		   
		   String scheme = urlMatcher.group(2);
		   if(!urlVal.isValidScheme(scheme)) {												
			   System.out.println("invalid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
			   validityRate++;
			   assertEquals(urlVal.isValid(value.text), value.valid);									
		   }   
		   
		   String authority = urlMatcher.group(4);
		   if ("file".equals(scheme) && "".equals(authority)) {
	       } 
		   else {
	           	if (!urlVal.isValidAuthority(authority)) {										
	           		System.out.println("invalid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
	           		validityRate++;
	           		assertEquals(urlVal.isValid(value.text), value.valid);									
	           	}
		   }

		   if (!urlVal.isValidPath(urlMatcher.group(5)) || !urlVal.isValidQuery(urlMatcher.group(7)) || !urlVal.isValidFragment(urlMatcher.group(9))) {
			    System.out.println("invalid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
			    validityRate++;
			   	assertEquals(urlVal.isValid(value.text), value.valid);
		   }
		   if(validityRate == 0){
			   System.out.println("valid URL: isValid() = "+urlVal.isValid(value.text)+"\t"+value.text);
			   assertEquals(urlVal.isValid(value.text), value.valid);										
		   }
	   }
   }
   
   public void testAnyOtherUnitTest()
   {
	   
   }
   /**
    * Create set of tests by taking the testUrlXXX arrays and
    * running through all possible permutations of their combinations.
    *
    * @param testObjects Used to create a url.
    */
   

}
